import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import { useProblemsStore, type ProblemItem, type ProblemSeverity } from '../stores/problems';
import { v4 as uuid } from 'uuid';

export class DiagnosticService {
  private static _instance: DiagnosticService | null = null;
  private _problems: any = null;
  private modelListeners = new Map<string, monaco.IDisposable>();
  private markerUpdateTimer: number | null = null;

  // 懒加载获取problems store
  private get problems() {
    if (!this._problems) {
      try {
        this._problems = useProblemsStore();
      } catch (error) {
        console.warn('Problems store not available yet, will retry later');
        return null;
      }
    }
    return this._problems;
  }

  static get instance(): DiagnosticService {
    if (!this._instance) {
      this._instance = new DiagnosticService();
    }
    return this._instance;
  }

  constructor() {
    // 监听模型变化事件，自动注册新模型
    monaco.editor.onDidCreateModel((model) => {
      this.registerModelMarkerListener(model);
    });

    // 监听模型销毁事件，清理监听器
    monaco.editor.onWillDisposeModel((model) => {
      this.unregisterModelMarkerListener(model);
    });

    // 注册已存在的模型
    monaco.editor.getModels().forEach(model => {
      this.registerModelMarkerListener(model);
    });

    // 初始收集
    this.collectProblems();
  }

  /**
   * 为指定模型注册标记监听器
   */
  private registerModelMarkerListener(model: monaco.editor.ITextModel) {
    const uri = model.uri.toString();
    
    // 如果已存在监听器，先清理
    if (this.modelListeners.has(uri)) {
      this.modelListeners.get(uri)?.dispose();
    }

    // 监听模型内容变化，延迟更新问题
    const listener = model.onDidChangeContent(() => {
      this.scheduleProblemsUpdate();
    });

    this.modelListeners.set(uri, listener);
  }

  /**
   * 移除指定模型的标记监听器
   */
  private unregisterModelMarkerListener(model: monaco.editor.ITextModel) {
    const uri = model.uri.toString();
    const listener = this.modelListeners.get(uri);
    if (listener) {
      listener.dispose();
      this.modelListeners.delete(uri);
    }
  }

  /**
   * 调度问题更新（防抖处理）
   */
  private scheduleProblemsUpdate() {
    if (this.markerUpdateTimer) {
      clearTimeout(this.markerUpdateTimer);
    }
    
    this.markerUpdateTimer = window.setTimeout(() => {
      this.collectProblems();
    }, 300); // 300ms 防抖
  }

  /**
   * 收集所有Monaco编辑器的诊断问题
   */
  collectProblems() {
    const allProblems: ProblemItem[] = [];
    
    // 遍历所有模型，收集其标记（markers）
    monaco.editor.getModels().forEach(model => {
      const uri = model.uri;
      const markers = monaco.editor.getModelMarkers({ resource: uri });
      
      markers.forEach(marker => {
        const problem: ProblemItem = {
          id: uuid(),
          severity: this.convertSeverity(marker.severity),
          message: marker.message,
          file: this.getReadablePath(uri.path),
          line: marker.startLineNumber,
          column: marker.startColumn,
        };
        
        allProblems.push(problem);
      });
    });

    // 更新问题存储
    const problemsStore = this.problems;
    if (problemsStore) {
      problemsStore.set(allProblems);
    }
  }

  /**
   * 转换Monaco标记严重级别为问题存储格式
   */
  private convertSeverity(severity: monaco.MarkerSeverity): ProblemSeverity {
    switch (severity) {
      case monaco.MarkerSeverity.Error:
        return 'error';
      case monaco.MarkerSeverity.Warning:
        return 'warning';
      case monaco.MarkerSeverity.Info:
        return 'info';
      default:
        return 'info';
    }
  }

  /**
   * 获取可读的文件路径
   */
  private getReadablePath(path: string): string {
    // 移除前缀 '/' 并使其更可读
    return path.startsWith('/') ? path.slice(1) : path;
  }

  /**
   * 手动添加问题
   */
  addProblem(problem: Omit<ProblemItem, 'id'>) {
    const fullProblem: ProblemItem = {
      ...problem,
      id: uuid(),
    };
    
    const problemsStore = this.problems;
    if (problemsStore) {
      problemsStore.add(fullProblem);
    }
  }

  /**
   * 清空所有问题
   */
  clearProblems() {
    const problemsStore = this.problems;
    if (problemsStore) {
      problemsStore.clear();
    }
  }

  /**
   * 为指定模型设置自定义标记
   */
  setModelMarkers(model: monaco.editor.ITextModel, markers: monaco.editor.IMarkerData[]) {
    monaco.editor.setModelMarkers(model, 'diagnostic-service', markers);
  }

  /**
   * 获取指定模型的标记
   */
  getModelMarkers(model: monaco.editor.ITextModel): monaco.editor.IMarker[] {
    return monaco.editor.getModelMarkers({ resource: model.uri });
  }

  /**
   * 清理服务
   */
  dispose() {
    // 清理所有监听器
    this.modelListeners.forEach(listener => listener.dispose());
    this.modelListeners.clear();

    // 清理定时器
    if (this.markerUpdateTimer) {
      clearTimeout(this.markerUpdateTimer);
      this.markerUpdateTimer = null;
    }

    this._problems = null;
    DiagnosticService._instance = null;
  }
}

// 导出获取单例实例的函数
export const getDiagnosticService = () => DiagnosticService.instance;